#include "Aplicacao.hpp"
#include <iostream>

Aplicacao::Aplicacao() : Layer(0) {

	this->bufferLe = new std::list<Bits*>();
}

Aplicacao::~Aplicacao() {

    delete this->bufferLe;
}

void Aplicacao::escreve(Bits* data) {

    this->send(data);
}

Bits* Aplicacao::le(void) {

	std::cout << "Le" << std::endl;
	boost::unique_lock<boost::mutex> lock(this->condm);

	//Verifica se há elemento. Caso não exista, espera a condição para liberar a thread
	this->bufferLeLock.lock();
		std::cout << this->bufferLe->size() << std::endl;
		while (this->bufferLe->size() == 0) {

			this->bufferLeLock.unlock();
			this->le_cond.wait(lock);
			this->bufferLeLock.lock();
		}

	std::cout << this->bufferLe->size() << std::endl;
	std::cout << "Reding" << std::endl;
		Bits* e = this->bufferLe->front();
		this->bufferLe->pop_front();
	this->bufferLeLock.unlock();    

	std::cout << "Readed" << std::endl;
	return e;
}

//Faz tratamento se necessário
void Aplicacao::newMessageToSend(Bits* b) {

	std::cout << "To send" << std::endl;
	//this->receive(b);
	this->getDownLayer()->send(b);
}

void Aplicacao::newReceivedMessage(Bits* b) {

	std::cout << "To rec" << std::endl;
	this->bufferLeLock.lock();
		this->bufferLe->push_back(b);
	this->bufferLeLock.unlock();

	//Acorda thread esperando dados
	boost::unique_lock<boost::mutex> lock(this->condm);
    this->le_cond.notify_all();
	std::cout << "End rec" << std::endl;
}
